﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.UIElements;


namespace JQMergeFramework
{

	public class UIAchievement : MonoBehaviour
	{

		public Scrollbar bar;
		public GameObject itemPrefab;
		public Transform itemParentNode;
		public ScrollRect mScrollView;

		public Text buildNameTxt,lockTipsTxt,buildNameDesTxt;
		public Text allAchievementTxt;
		
		private List<CardItem> itemlist = new List<CardItem>();
		private float distance = 0;
	
		
		private int selectIndex = 0;
		private int lastSelectIndex = 0;
		private float time = 0;
		
		//目标点的值
		private float _tagetV = 0;

		private float target
		{
			get { return _tagetV; }
			set
			{
				_tagetV = value;
			}
		}

		private RectTransform itemPrefabRect;

		private List<CityTargetCfg> mCityTargetCfgList;

		private bool isRun = false;

		private RectTransform mRectTrans;
		private int cityInfoCount = 0;
		private float maxWeight;
		
		private Stack<CardItem> _pool = new Stack<CardItem>();
		private int VisibleCount = 3;
		
		// Use this for initialization
		void Awake()
		{
			mRectTrans = this.GetComponent<RectTransform>();
			
			itemPrefabRect = itemPrefab.GetComponent<RectTransform>();
			UIManager.Instance.AddBtnListener(this.transform);
			
			mCityTargetCfgList = TableConfig.Instance.CityTargetCfgList;
			
			cityInfoCount = mCityTargetCfgList.Count;
			
			maxWeight = itemPrefabRect.rect.width * cityInfoCount;
			
			distance = 1.0f / ((float)cityInfoCount - 1);
			//总距离
			mScrollView.content.sizeDelta = new Vector2(maxWeight,mScrollView.content.rect.height);
		}
		

		void OnBtnClick(Transform trans)
		{
			AudioManager.Instance.Play(AudioName.Click);
			switch (trans.name)
			{
				case "BtnClose":
					Close();
					break;
			}
		}

		public	void Open()
		{
			GetComponent<UIPopAnimate>().PopStart();

			//Scrollbar 组件有一个初始化的刷新。会重置设置的值。延迟0.2秒再展示
			CommonFun.DelayCallback(() =>
			{
				LocationIndex();
				isRun = true;
			},0.2F);
		}

		void LocationIndex()
		{
			int lv = DataManager.Instance.AchievementFinishIndex;
			int num = TableConfig.Instance.GetFinishedTargetNum(lv);
	
			allAchievementTxt.text = string.Format("{0}/{1}", num, cityInfoCount);
			target = distance * (num-1) <= 0? 0: distance * (num-1);
			target = target > 1 ? 1 : target;

			int value = (int) (target / distance + 0.5f);
			selectIndex = value;
			bar.value = target;
			
		
			lastSelectIndex = selectIndex;

			//至少保证
			if (itemlist.Count < VisibleCount)
			{
				int diff = VisibleCount - itemlist.Count;
				for (int i = 0; i < diff; ++i)
				{
					itemlist.Add(GetFromPool());
				}
			}
			
			//指定坐标，只展示三个。
			for (int i = 0; i < itemlist.Count; i++)
			{
				if (selectIndex >= cityInfoCount-1)
				{
					itemlist[i].BindCityCfg(selectIndex-i,mCityTargetCfgList[selectIndex-i],bar,maxWeight,distance);
				}
				else if (selectIndex > 0)
				{
					itemlist[i].BindCityCfg((selectIndex-1)+i,mCityTargetCfgList[(selectIndex-1)+i],bar,maxWeight,distance);
				}
				else
				{
					itemlist[i].BindCityCfg(i,mCityTargetCfgList[i],bar,maxWeight,distance);
				}
			}
			
			UIRefreshCityInfo(mCityTargetCfgList[selectIndex]);
			RefreshItemPos();
		}



		

		public void PointUp()
		{
			bar.value = bar.value > 1 ? 1 : bar.value;
			int value = (int) (bar.value / distance + 0.5f);
			selectIndex = value;
			target = distance * value;
			
			for (int i = 0; i < itemlist.Count; i++)
			{
				if (itemlist[i].mIndex == selectIndex)
				{
					UIRefreshCityInfo(itemlist[i].CityCfg);
					break;
				}
			}
		
			lastSelectIndex = selectIndex;
		}

		// Update is called once per frame
		void Update()
		{

			if (!isRun)
			{
				return;
			}
			
			if (Input.GetMouseButtonUp(0))
			{
				PointUp();
			}
			
			if (Input.GetMouseButton(0))
			{
				time += Time.deltaTime;
				RefreshItemPos();
				return;
			}

			if (target != bar.value)
			{
				if (bar.value < target)
					bar.value += Time.deltaTime / 5;
				if (bar.value >= target)
					bar.value -= Time.deltaTime / 5;
				
				float tValue = bar.value - target;
				
				if (Mathf.Abs(tValue) < 0.01f)
				{
					bar.value = target;
				}
				RefreshItemPos();
			}
		}


		void RefreshItemPos()
		{

			if (itemlist.Count <= 0)
			{
				return;
			}
			
			for (int i = itemlist.Count-1; i >= 0; --i)
			{
				if (IsReleaseItem(itemlist[i].mIndex))
				{
					ReleaseItem(itemlist[i]);
					itemlist.RemoveAt(i);
				}
			}
				
			int index = itemlist[0].mIndex - 1;
			int afterIndex = itemlist[itemlist.Count - 1].mIndex + 1;
				
			while (index >= 0)
			{
				if (IsReleaseItem(index))
					break;
				CardItem item = AppendItem(index);
				index--;
				itemlist.Insert(0, item);
			}
 
			while (afterIndex < cityInfoCount)
			{
				if (IsReleaseItem(afterIndex))
					break;
				CardItem item = AppendItem(afterIndex);
				afterIndex++;
				itemlist.Add(item);
			}
		}


		void FixedUpdate()
		{
			for (int i = 0; i < itemlist.Count; i++)
			{
				itemlist[i].UpdatePos();
			}
		}

		void UIRefreshCityInfo(CityTargetCfg cfg)
		{
			buildNameTxt.text = cfg.name;
			lockTipsTxt.text = string.Format("解锁条件：<color=#FF3312>合成大楼至{0}层</color>", cfg.lv);
			buildNameDesTxt.text = cfg.describe;
		}


		
		void Close()
		{
			
			isRun = false;
			GetComponent<UIPopAnimate>().PopEnd();
		}
		
		
		private CardItem GetFromPool()
		{
			if (_pool.Count > 0)
			{
				return _pool.Pop();
			}
			else
			{
				GameObject go = Instantiate<GameObject>(itemPrefab.gameObject,itemParentNode);
				go.SetActive(false);
				return go.GetComponent<CardItem>();
			}
		}
		
		 
		private CardItem AppendItem(int index)
		{
			CardItem item = GetFromPool();
			item.BindCityCfg(index,mCityTargetCfgList[index],bar,maxWeight,distance);
			return item;
		}
		
		
		//回收
		private void ReleaseItem(CardItem item)
		{
			item.gameObject.SetActive(false);
			_pool.Push(item);
		}
		
		 //判断是否回收
		private bool IsReleaseItem(int index)
		{
			//判断当前的索引 是否在中心点的-1 or +1
			int value = (int) (bar.value / distance + 0.5f);
			
			if (MathF.Abs(index-value) > 1)
			{
				return true;
			}
			return false;
		}

		
		private void OnDestroy()
		{
			for (int i = 0; i < _pool.Count; i++)
			{
				Destroy(_pool.Pop().gameObject);
			}
		}
		
	}
	
	

}
